#ifndef __OgreAML_MeshDefinitionManager_H__
#define __OgreAML_MeshDefinitionManager_H__
#pragma once

// Include stuff
#include "OgreAMLPrerequisites.h"

#include <OgreResourceManager.h>
#include <OgreSingleton.h>
#include "OgreMeshDefinition.h"

namespace Ogre
{
	/**
	 * @brief Class for mananig mesh loading settings
	 */
	class _OgreAMLExport MeshDefinitionManager : public ResourceManager,
		public Singleton<MeshDefinitionManager>
	{
	public:
		/**
		 * @brief Default constructor
		 */
		MeshDefinitionManager();

		/**
		 * @brief Virtual destructor
		 */
		virtual ~MeshDefinitionManager();

		/**
		 * @brief Initialising this maneger
		 * @remarks Internal use only
		 */
		void _initialise();

		/**
		 * @brief Shutting down this manager
		 * @remarks Internal use only
		 */
		void _shutdown();

		/**
		 * @brief Overridden from ScriptLoader
		 * @copydoc ScriptLoader::parseScript
		 */
		void parseScript( DataStreamPtr& stream, const String& groupName );

	protected:

		/**
		 * @brief Overridden from ResourceManager
		 * @copycod ResourceManager::createImpl
		 */
		Resource* createImpl( const String& name, ResourceHandle handle,
			const String& group, bool isManual, ManualResourceLoader* loader,
			const NameValuePairList* createParams );

	protected:
		/**
		 * @brief Specialised struct to hold internal data
		 *	of mesh definition script parser
		 */
		struct ScriptParserCookie
		{
			/**
			 * @brief default constructor
			 */
			ScriptParserCookie();

			/// Weak reference to a data stream which is the source of the script
			DataStreamPtr stream;
			/// The name of a resource group which should be used if any resources are created during the script parse
			String groupName;
			/// The current parsing resource
			MeshDefinitionPtr resource;
			/// The current parsing string line
			String line;
			/// The current parsing line number
			size_t lineNum;
		};

	protected:
		/**
		 * @brief Reading a single line from script
		 * @returns Return false if ends of file. Otherwise return true
		 */
		bool readSingleLine( ScriptParserCookie& cookie );

		/**
		 * @brief Implemmentation of reading a single line from script file
		 * @returns Return false if ends of file. Otherwise return true
		 */
		bool readSingleLineImpl( ScriptParserCookie& cookie );

		/**
		 * @brief Parsing single line
		 */
		void parseSingleLine( ScriptParserCookie& cookie );

		/**
		 * @brief Parsing script attribute
		 */
		void parseAttribute( ScriptParserCookie& cookie, const String& name, const String& value );

		/**
		 * @brief Parsing right brase '}' script attribute
		 */
		void parseRightBraceAttribute( ScriptParserCookie& cookie, const String& value );

		/**
		 * @brief Parsing 'file' script attribute
		 */
		void parseFileAttribute( ScriptParserCookie& cookie, const String& value );

		/**
		 * @brief Parsing 'lod' script attribute
		 */
		void parseLodAttribute( ScriptParserCookie& cookie, const String& value );

		/**
		 * @brief Parsing 'lod_method' script attribute
		 */
		void parseLodMethodAttribute( ScriptParserCookie& cookie, const String& value );

		/**
		 * @brief Parsing 'progressive_reduction_method' script attribute
		 */
		void parseProgressiveReductionMethodAttribute( ScriptParserCookie& cookie, const String& value );

		/**
		 * @brief Parsing 'reduction' script attribute
		 */
		void parseReductionAttribute( ScriptParserCookie& cookie, const String& value );

		/**
		 * @brief Parsing 'progressive_lod_values' script attribute
		 */
		void parseProgressiveLodValuesAttribute( ScriptParserCookie& cookie, const String& value );

		/**
		 * @brief Parsing 'preload_lods' script attribute
		 */
		void parsePreloadLobdsAttribute( ScriptParserCookie& cookie, const String& value );
	};

} // end of namespace Ogre

#endif // include guard, end of #ifndef __OgreAML_MeshDefinitionManager_H__
